//
//  BigLetterView.m
//  <17.1> TypingTutor
//
//  Created by chen on 16/9/19.
//  Copyright © 2016年 tyrad. All rights reserved.
//

#import "BigLetterView.h"

@interface BigLetterView ()
{
    NSEvent *_mouseDownEvent;
    BOOL _highlighted; //高亮时候表示可以释放拖拽了
}
@end

@implementation BigLetterView

#pragma mark -- 拖拽来 （作为拖拽的目的地）

- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender{
    NSLog(@"draggingEntered:");
    if ([sender draggingSource] == self) {
        return NSDragOperationNone ;
    }
    _highlighted = YES  ;
    [self setNeedsDisplay:YES];
    return NSDragOperationCopy ;
}

- (void)draggingExited:(id<NSDraggingInfo>)sender{
    NSLog(@"draggingExited:");
    _highlighted = NO ;
    [self setNeedsDisplay:YES];
}

- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender{
    
    return YES ;
}

//处理拖拽事件
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender{
    
    NSPasteboard *pd = [sender draggingPasteboard];
    if ([self readFromPasteboard:pd] == NO) { //从粘贴板复制进来
        NSLog(@"Error:Could not read from draggingPasteboard");
        return NO ;
    }
    return YES ;
}

- (void)concludeDragOperation:(id<NSDraggingInfo>)sender{
    
    NSLog(@"concludeDragOperation:");
    _highlighted = NO ;
    [self setNeedsDisplay:YES];
}




#pragma mark -- 拖拽去

//成为拖动作的源，必须实现方法如下：
//- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag NS_DEPRECATED_MAC(10_0, 10_7, "Use -draggingSession:sourceOperationMaskForDraggingContext: instead");

//这个方法自动调用2次：:OutsideApplication/inApplication 程序间动作或者程序内部动作
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context{
    //NSDraggingContextOutsideApplication = 0,
    //NSDraggingContextWithinApplication
    return NSDragOperationCopy | NSDragOperationDelete; //(为了满足删除,添加 |Delete ,拖到垃圾站就会删除)
}

//开始拖拽操作  NS_DEPRECATED_MAC(10_0, 10_7, "Use -beginDraggingSessionWithItems:event:source: instead");
//-(void)dragImage:(NSImage *)image at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag

- (void)mouseDown:(NSEvent *)event{
    _mouseDownEvent = event ;  
}

- (void)mouseDragged:(NSEvent *)event{
    
    NSPoint down = [_mouseDownEvent locationInWindow];
    NSPoint drag = [event locationInWindow];
    
    float distance = hypot(down.x - drag.x, down.y-drag.y);
    if (distance < 3) {
        return ;
    }
    
    if ([_myString length] == 0 ) {
        return ;
    }
    
    NSSize s = [_myString sizeWithAttributes:_attributes];
    //需要拖拽操作的对象
    NSImage *anImage = [[NSImage alloc]initWithSize:s];
    //在要绘制的图片创建矩形区域
    NSRect imagBounds ;
    imagBounds.origin = NSZeroPoint ;
    imagBounds.size = s ;
    //图片上绘制字符串
    [anImage lockFocus];
    [self drawStringCenteredIn:imagBounds];
    [anImage unlockFocus];
    
    //获取点击事件的位置
    NSPoint p = [self convertPoint:down fromView:nil]; //nil 表示相对于window
    
    //从图片中心开始拖
    p.x = p.x - s.width/2;
    p.y = p.y - s.height/2;
    
    //获取粘贴板
    NSPasteboard *pd = [NSPasteboard pasteboardWithName:NSDragPboard];
    //字符串放到粘贴板
    [self writeTPPasteboard:pd];
    
    //开始操作
    [self dragImage:anImage at:p offset:NSZeroSize event:_mouseDownEvent pasteboard:pd source:self slideBack:YES];
}

- (void)draggedImage:(NSImage *)image
             endedAt:(NSPoint)screenPoint
           operation:(NSDragOperation)operation{
    
    if (operation == NSDragOperationDelete) { //拖到垃圾站就会删除
        [self setMyString:@""];
    }
}

#pragma mark -- PasteBoard 

//写
- (void)writeTPPasteboard:(NSPasteboard *)pd{
    
    //复制数据 到粘贴板
    [pd clearContents];
    [pd writeObjects:@[self.myString]];
    
}


//读
- (BOOL)readFromPasteboard:(NSPasteboard *)pd{
    
    NSArray *classes = @[ [NSString class] ];
    NSArray *objects = [pd readObjectsForClasses:classes options:nil];
    
    if ([objects count] > 0) {
        
        //从粘贴板中读取数据
        NSString *value = [objects objectAtIndex:0];
        if (value.length == 1) { //实际只会有1个字符
            [self setMyString:value];
            
            return YES ;
        }
    }
    return NO ;
}


- (IBAction)cut:(id)sender{
    [self copy:sender];
    [self setMyString:@""];
}

- (IBAction)copy:(id)sender{
    NSPasteboard *pd = [NSPasteboard generalPasteboard];
    [self writeTPPasteboard:pd];
}
- (IBAction)paste:(id)sender{
    NSPasteboard *pd = [NSPasteboard generalPasteboard];
    if ([self readFromPasteboard:pd] == NO) {
        NSBeep() ; //哔哔
    }
}


#pragma mark -- SavePDF
/*******************************/

//将数据生成pdf非常容易, NSView有相关方法
- (IBAction)savePDF:(id)sender
{
    //NSData *data = [self dataWithPDFInsideRect:self.bounds];
    __block NSSavePanel *panel = [NSSavePanel  savePanel];
    
    [panel setAllowedFileTypes:@[@"pdf"]];
    
    [panel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) {
        
        if (result == NSOKButton) {
            
            NSRect r = [self bounds];
            NSData *data = [self dataWithPDFInsideRect:r];
            NSError *error ;
            
            BOOL successFul = [data writeToURL:[panel URL] options:0 error:&error];
            
            if (successFul == NO) {
                NSAlert *a = [NSAlert alertWithError:error];
                [a runModal];
            }
        }
    }];
}

/*************拖放******************/

- (void)awakeFromNib{
    
    _myString = @"" ;
    [self prepareAttributes];
    
    //注册支持复制string
    [self registerForDraggedTypes:@[NSPasteboardTypeString]];
    
    
}

- (void)prepareAttributes{
    
    _attributes = @{}.mutableCopy ;
    
    _attributes[NSFontAttributeName] = [NSFont userFontOfSize:74];
    _attributes[NSForegroundColorAttributeName] = [NSColor redColor];
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:self.bounds];
    
    if (_highlighted) {
        NSGradient *gr ;
        gr = [[NSGradient alloc]initWithStartingColor:[NSColor whiteColor] endingColor:[NSColor greenColor]];
        [gr drawInRect:self.bounds relativeCenterPosition:NSZeroPoint];
    }else {
        
        [[NSColor greenColor] setFill];
        [NSBezierPath fillRect:self.bounds];
    }
    
    //绘制文字
    [self drawStringCenteredIn:self.bounds];
    
    //是否为窗口的first responder
    //绘制毛边
    if ([[self  window]firstResponder] == self && [NSGraphicsContext currentContextDrawingToScreen]) {
        
        [NSGraphicsContext saveGraphicsState];
        NSSetFocusRingStyle(NSFocusRingOnly);
        [NSBezierPath fillRect:self.bounds];
        [NSGraphicsContext restoreGraphicsState];
        
        //蓝色填充
        //[[NSColor redColor] set];
        //[NSBezierPath setDefaultLineWidth:4];
        //[NSBezierPath strokeRect:self.bounds];
    }
}


- (void)drawStringCenteredIn:(NSRect)r{
    
    NSSize strSize = [self.myString sizeWithAttributes:_attributes];
    
    NSPoint strOrigin ;
    strOrigin.x = r.origin.x + (r.size.width - strSize.width)/2;
    strOrigin.y = r.origin.y + (r.size.height - strSize.height)/2 ;
    
    [_myString drawAtPoint:strOrigin withAttributes:_attributes];
}



/*******************************/


- (void)setMyString:(NSString *)myString{
    _myString = myString ;
    NSLog(@"now myString is %@", myString);
    
    [self setNeedsDisplay:YES];
}


- (BOOL)becomeFirstResponder{
    [self setNeedsDisplay:YES];
    return YES ;
}

- (BOOL)resignFirstResponder{
//    [self setNeedsDisplay:YES];
    [self setKeyboardFocusRingNeedsDisplayInRect:self.bounds] ;
    return YES;
}


//重载，处理键盘事件
- (BOOL)acceptsFirstResponder{
    return YES ;
}


#pragma mark -- KeyBoard Actions

/*******************************/

- (void)keyDown:(NSEvent *)event{
    [self interpretKeyEvents:@[event]];
}


- (void)insertText:(NSString *)insertString{ //重载方法
    [self setMyString:insertString];
}


- (void)insertTab:(id)sender{
    [[self window]selectKeyViewFollowingView:self];//重载方法
}

- (void)insertBacktab:(id)sender{
    [[self window]selectKeyViewPrecedingView:self];//重载方法
}

- (void)deleteBackward:(id)sender{//重载方法 退格键盘
    [self setMyString:@""];
}


@end
















